﻿#include "AstWorkerImpl.h"

#include "../lib/env.h"
#include "../lib/function.h"
#include "../lib/function_group.h"

#include "AstWorker.h"

class AstWorkerImpl::AstWorkerImplPrivate :public QObject, public AstWorker
{
public:
	void		*env;
	struct function_group_s * function_group_ptr;
public:
	AstWorkerImplPrivate(QObject*parent) :QObject(parent)
	{
		function_group_ptr = nullptr;
		env = nullptr;
		env_create(&env);
	}
	~AstWorkerImplPrivate()
	{
		if (env)
			env_free(env);
	}
	void setFunctions(void*funcs)
	{
		function_group_ptr = (struct function_group_s*)funcs;
		env_set_function_group(env, function_group_ptr, 0);
	}
	///
	virtual int parseString(const QString&s) override
	{
		if (!env)
			return -1;

		int r = env_parse_string(env, s.toUtf8().toStdString().c_str());

		return r;
	}
	virtual int run() override
	{
		if (!env)
			return -1;

		return env_exec(env);
	}
};

AstWorkerImpl::AstWorkerImpl(QObject *parent)
	: QObject(parent),private_ptr(new AstWorkerImplPrivate(this))
{
}

AstWorkerImpl::~AstWorkerImpl()
{
}

AstWorker* AstWorkerImpl::operator()()
{
	return dynamic_cast<AstWorker*>(private_ptr);
}

void AstWorkerImpl::setFunctions(void*funcs)
{
	private_ptr->setFunctions(funcs);
}

////////////////////////////////////////////////////////
//
class AstWorkerImplGroup::AstWorkerImplGroupPrivate :public QObject
{
public:
public:
	AstWorkerImplGroupPrivate(QObject*parent):QObject(parent)
	{}
};
AstWorkerImplGroup::AstWorkerImplGroup(QObject*parent)
	:KGroupVectorPtrT<AstWorkerImpl>(parent),private_ptr(new AstWorkerImplGroupPrivate(this))
{
}

AstWorkerImpl* AstWorkerImplGroup::createAstWorker()
{
	AstWorkerImpl*w = new AstWorkerImpl(this);
	addItem(w);
	return w;
}
AstWorkerImpl* AstWorkerImplGroup::queryAstWorker(AstWorker*_)
{
	for each(auto a in *items()) {
		if (_ == a->operator()())
			return a;
	}
	return nullptr;
}
void AstWorkerImplGroup::closeAstWorker(AstWorker*_)
{
	AstWorkerImpl*p = queryAstWorker(_);
	closeAstWorker(p);
}

void AstWorkerImplGroup::closeAstWorker(AstWorkerImpl*_)
{
	if (_)
		delItem(_, true);
}
